#include <sys/types.h>
#include <sys/wait.h>
#include <iostream>
#include <unistd.h>
#include <signal.h>
// 创建子进程，故意不回收
// 如果waitpid成功等待到一个子进程，它会返回该子进程的PID
// 返回值为0：表示没有子进程已经退出（仅当使用了WNOHANG选项时）。
// 返回值为-1：表示发生错误，具体错误类型可以通过errno获取。

// pid：指定要等待的子进程的PID。
//-1：等待任意子进程。
// 0：等待同一个进程组的任意子进程。
// 正数：等待指定的子进程

void signal_handler(int signo)
{
    std::cout << "子进程发送信号! signo: " << signo << std::endl;
    while (waitpid(0, nullptr, WNOHANG) > 0) // 一次等待所有的子进程，这样下次处理信号就不用内核再做处理，直接返回就行
    {
    }
    std::cout << "此次回收子进程成功!" << std::endl;
}

int main()
{
    struct sigaction sa, oldsa;
    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);          // 全部清零
    ::sigaction(SIGCHLD, &sa, &oldsa); // 把SIGCHLD进行修改
    if (sigaction(SIGCHLD, &sa, NULL) == -1)
    {
        std::cerr << "Sigaction failed" << std::endl;
        return 1;
    }
    pid_t pid = ::fork();
    if (pid == 0)
    {
        sleep(5);
        printf("我是子进程，我结束了！");
        exit(0);
    }
    while (true)
    {
        printf("我是父进程,我的pid是: %d,子进程的pid是: %d\n", getpid(), pid);
        sleep(1);
    }
    return 0;
}